﻿namespace FFF.Test.DataAccess.Framework
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.Data;
    using System.Data.Common;
    using System.Data.SqlClient;
    using System.Diagnostics;
    using System.Linq;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.Threading.Tasks;
    using Microsoft.EntityFrameworkCore;
    using Microsoft.EntityFrameworkCore.Diagnostics;
    using Microsoft.EntityFrameworkCore.Metadata;
    using FFF.Test.DataAccess.Framework.Configuration.Dto;
    using FFF.Test.Util.Consts;
    using Z.EntityFramework.Extensions;

    /// <summary>
    /// cmmand 
    /// </summary>
    public class EFCommandInterceptor : DbCommandInterceptor
    {
        /// <summary>
        /// 执行excutquery的拦截
        /// </summary>
        /// <param name="command">命令</param>
        /// <param name="interceptionContext">拦截上下文</param>
        public override void NonQueryExecuted(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
        {
            base.NonQueryExecuted(command, interceptionContext);
            this.LogInfo("EFCommandInterceptor.NonQueryExecuted", interceptionContext.Result.ToString(), command.CommandText);
        }

        /// <summary>
        /// 执行query
        /// </summary>
        /// <param name="command">命令</param>
        /// <param name="interceptionContext">拦截</param>
        public override void NonQueryExecuting(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
        {
            base.NonQueryExecuting(command, interceptionContext);
            this.LogInfo("EFCommandInterceptor.NonQueryExecuting", interceptionContext.EventData.ToString(), command.CommandText);
        }

        /// <summary>
        /// 执行reader
        /// </summary>
        /// <param name="command">命令</param>
        /// <param name="interceptionContext">拦截</param>
        public override void ReaderExecuted(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
        {
            base.ReaderExecuted(command, interceptionContext);
            this.LogInfo("EFCommandInterceptor.ReaderExecuted", interceptionContext.Result.ToString(), command.CommandText);
        }

        /// <summary>
        /// reader执行
        /// </summary>
        /// <param name="command">执行</param>
        /// <param name="interceptionContext">拦截</param>
        public override void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
        {
            base.ReaderExecuting(command, interceptionContext);
            this.LogInfo("EFCommandInterceptor.ReaderExecuting", interceptionContext.EventData.ToString(), command.CommandText);
        }

        /// <summary>
        /// scalar执行
        /// </summary>
        /// <param name="command">命令</param>
        /// <param name="interceptionContext">拦截</param>
        public override void ScalarExecuted(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
        {
            base.ScalarExecuted(command, interceptionContext);
            this.LogInfo("EFCommandInterceptor.ScalarExecuted", interceptionContext.Result.ToString(), command.CommandText);
        }

        /// <summary>
        /// scaclr
        /// </summary>
        /// <param name="command">命令</param>
        /// <param name="interceptionContext">拦截</param>
        public override void ScalarExecuting(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
        {
            base.ScalarExecuting(command, interceptionContext);
            this.LogInfo("EFCommandInterceptor.ScalarExecuting", interceptionContext.EventData.ToString(), command.CommandText);
        }

        /// <summary>
        /// noquerrr执行错误
        /// </summary>
        /// <param name="command">命令</param>
        /// <param name="interceptionContext">上下文</param>
        /// <param name="exception">异常</param>
        public override void NonQueryError(DbCommand command, DbCommandInterceptionContext<int> interceptionContext, Exception exception)
        {
            base.NonQueryError(command, interceptionContext, exception);
            this.LogInfo("EFCommandInterceptor.NonQueryError", interceptionContext.EventData.ToString(), command.CommandText, exception.Message);
        }

        /// <summary>
        /// reader错误
        /// </summary>
        /// <param name="command">命令</param>
        /// <param name="interceptionContext">上下文</param>
        /// <param name="exception">异常</param>
        public override void ReaderError(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext, Exception exception)
        {
            base.ReaderError(command, interceptionContext, exception);
            this.LogInfo("EFCommandInterceptor.NonQueryError", interceptionContext.EventData.ToString(), command.CommandText, exception.Message);
        }

        /// <summary>
        /// scalar错误
        /// </summary>
        /// <param name="command">命令</param>
        /// <param name="interceptionContext">上下文</param>
        /// <param name="exception">异常</param>
        public override void ScalarError(DbCommand command, DbCommandInterceptionContext<object> interceptionContext, Exception exception)
        {
            base.ScalarError(command, interceptionContext, exception);
            this.LogInfo("EFCommandInterceptor.NonQueryError", interceptionContext.EventData.ToString(), command.CommandText, exception.Message);
        }

        private void LogInfo(string method, string command, string commandText)
        {
            Console.WriteLine("Intercepted on: {0} \n {1} \n {2}", method, command, commandText);
        }

        private void LogInfo(string method, string command, string commandText, string exception)
        {
            Console.WriteLine("Intercepted on: {0} \n {1} \n {2} \n {3}", method, command, commandText, exception);
        }

        ///// <summary>
        ///// 
        ///// </summary>
        ///// <param name="command">command</param>
        ///// <param name="connectionString">连接字符串</param>
        //private void ResetConnection(DbCommand command, string connectionString)
        //{
        //    if (command.Connection.State == ConnectionState.Open)
        //    {
        //        if (command.CommandText.Contains("@@ROWCOUNT"))
        //        {
        //            command.Connection.Close();
        //            command.Connection.ConnectionString = "server=127.0.0.1;database=Test;uid=sa;pwd=12344321;MultipleActiveResultSets=true;";
        //            command.Connection.Open();
        //        }
        //    }
        //}
    }
}